package com.iiiu.payment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iiiu.payment.domain.dto.LoginDTO;
import com.iiiu.payment.domain.dto.PageQueryDTO;
import com.iiiu.payment.domain.dto.RegisterDTO;
import com.iiiu.payment.domain.dto.UserDTO;
import com.iiiu.payment.domain.entity.User;
import com.iiiu.payment.mapper.UserMapper;
import com.iiiu.payment.service.UserService;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public UserDTO register(RegisterDTO registerDTO) {
        // 检查用户名是否已存在
        if (existsByUsername(registerDTO.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }

        // 创建用户实体
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setNickname(registerDTO.getNickname());
        user.setPassword(encryptPassword(registerDTO.getPassword()));
        user.setRemark(registerDTO.getRemark());
        user.setRole("USER"); // 默认角色
        user.setIsDelete(0);

        // 保存用户
        save(user);

        // 转换为DTO返回
        return convertToDTO(user);
    }

    @Override
    public UserDTO login(LoginDTO loginDTO) {
        // 根据用户名查询用户
        User user = baseMapper.findByUsername(loginDTO.getUsername());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 验证密码
        if (!encryptPassword(loginDTO.getPassword()).equals(user.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        // 检查用户是否被删除
        if (user.getIsDelete() == 1) {
            throw new RuntimeException("用户已被删除");
        }

        // 使用Sa-Token进行登录
        StpUtil.login(user.getId());
        
        // 在Session中存储用户信息
        StpUtil.getSession().set("user", user);
        
        UserDTO userDTO = convertToDTO(user);
        // 将token添加到返回的DTO中
        userDTO.setToken(StpUtil.getTokenValue());
        
        return userDTO;
    }

    @Override
    public UserDTO getUserByUsername(String username) {
        User user = baseMapper.findByUsername(username);
        return user != null ? convertToDTO(user) : null;
    }

    @Override
    public UserDTO getUserById(Long id) {
        User user = getById(id);
        return user != null ? convertToDTO(user) : null;
    }

    @Override
    public UserDTO updateUser(UserDTO userDTO) {
        User user = getById(userDTO.getId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 更新用户信息
        if (StringUtils.hasText(userDTO.getNickname())) {
            user.setNickname(userDTO.getNickname());
        }
        if (StringUtils.hasText(userDTO.getRemark())) {
            user.setRemark(userDTO.getRemark());
        }
        if (StringUtils.hasText(userDTO.getRole())) {
            user.setRole(userDTO.getRole());
        }

        updateById(user);
        return convertToDTO(user);
    }

    @Override
    public boolean deleteUser(Long id) {
        User user = getById(id);
        if (user == null) {
            return false;
        }

        // 软删除
        user.setIsDelete(1);
        return updateById(user);
    }

    @Override
    public IPage<UserDTO> getUserPage(PageQueryDTO pageQueryDTO) {
        Page<User> page = new Page<>(pageQueryDTO.getCurrent(), pageQueryDTO.getSize());
        
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getIsDelete, 0);
        
        // 关键词搜索
        if (StringUtils.hasText(pageQueryDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                .like(User::getUsername, pageQueryDTO.getKeyword())
                .or()
                .like(User::getNickname, pageQueryDTO.getKeyword())
            );
        }
        
        // 排序
        if (StringUtils.hasText(pageQueryDTO.getSortField())) {
            if ("asc".equalsIgnoreCase(pageQueryDTO.getSortOrder())) {
                queryWrapper.orderByAsc(User::getCreateTime);
            } else {
                queryWrapper.orderByDesc(User::getCreateTime);
            }
        } else {
            queryWrapper.orderByDesc(User::getCreateTime);
        }

        IPage<User> userPage = baseMapper.selectPage(page, queryWrapper);
        
        // 转换为DTO
        IPage<UserDTO> dtoPage = new Page<>();
        BeanUtils.copyProperties(userPage, dtoPage);
        List<UserDTO> dtoList = userPage.getRecords().stream()
            .map(this::convertToDTO)
            .collect(Collectors.toList());
        dtoPage.setRecords(dtoList);
        
        return dtoPage;
    }

    @Override
    public boolean existsByUsername(String username) {
        return baseMapper.existsByUsername(username);
    }

    @Override
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 验证旧密码
        if (!encryptPassword(oldPassword).equals(user.getPassword())) {
            throw new RuntimeException("旧密码错误");
        }

        // 更新密码
        user.setPassword(encryptPassword(newPassword));
        return updateById(user);
    }

    /**
     * 密码加密
     * @param password 原始密码
     * @return 加密后的密码
     */
    private String encryptPassword(String password) {
        return DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 转换为DTO
     * @param user 用户实体
     * @return 用户DTO
     */
    private UserDTO convertToDTO(User user) {
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        return userDTO;
    }
}